package com.car.rental.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.car.rental.common.core.exception.BusinessException;
import com.car.rental.common.core.response.PageResult;
import com.car.rental.common.core.response.ResponseResult;
import com.car.rental.common.utils.JwtUtils;
import com.car.rental.user.entity.User;
import com.car.rental.user.entity.UserRole;
import com.car.rental.user.mapper.UserMapper;
import com.car.rental.user.mapper.UserRoleMapper;
import com.car.rental.user.model.request.UpdatePasswordRequest;
import com.car.rental.user.model.request.UpdateUserRequest;
import com.car.rental.user.model.request.UserSearchRequest;
import com.car.rental.user.model.response.UserInfoResponse;
import com.car.rental.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;
    private final UserRoleMapper userRoleMapper;
    private final JwtUtils jwtUtils;
    private final PasswordEncoder passwordEncoder;
    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
    
    @Value("${upload.base-path}")
    private String basePath;
    
    @Value("${upload.paths.avatar}")
    private String avatarPath;

    @Override
    public ResponseResult<UserInfoResponse> getUserInfo(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        UserInfoResponse response = new UserInfoResponse();
        BeanUtils.copyProperties(user, response);
        return ResponseResult.success(response);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> updateUserInfo(Long userId, UpdateUserRequest request) {
        log.info("开始更新用户信息: userId={}, request={}", userId, request);
        
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 检查并更新用户名
        String newUsername = request.getUsername();
        if (!user.getUsername().equals(newUsername)) {
            log.info("用户名变更: 从 {} 变更为 {}", user.getUsername(), newUsername);
            
            // 检查新用户名是否被使用
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getUsername, newUsername)
                   .ne(User::getId, userId);
            if (userMapper.selectCount(wrapper) > 0) {
                throw new BusinessException("用户名已被使用");
            }
            
            user.setUsername(newUsername);
        }
        
        user.setPhone(request.getPhone());
        user.setEmail(request.getEmail());
        
        int rows = userMapper.updateById(user);
        log.info("更新结果: 影响行数={}", rows);
        
        if (rows > 0) {
            return ResponseResult.success();
        } else {
            throw new BusinessException("更新用户信息失败");
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<String> updateAvatar(Long userId, MultipartFile file) {
        try {
            // 1. 获取用户信息
            User user = userMapper.selectById(userId);
            if (user == null) {
                throw new BusinessException("用户不存在");
            }

            // 2. 删除旧头像文件
            String oldAvatarUrl = user.getAvatar();
            if (StringUtils.hasText(oldAvatarUrl)) {
                String oldFileName = oldAvatarUrl.substring(oldAvatarUrl.lastIndexOf("/") + 1);
                File oldFile = new File(basePath + avatarPath + oldFileName);
                if (oldFile.exists()) {
                    if (!oldFile.delete()) {
                        log.warn("删除旧头像文件失败: {}", oldFile.getAbsolutePath());
                    } else {
                        log.info("成功删除旧头像文件: {}", oldFile.getAbsolutePath());
                    }
                }
            }

            // 3. 保存新头像文件
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null) {
                throw new BusinessException("文件名不能为空");
            }

            String fileName = UUID.randomUUID().toString() + 
                originalFilename.substring(originalFilename.lastIndexOf("."));
            
            File targetFile = new File(basePath + avatarPath + fileName);
            file.transferTo(targetFile);
            
            // 4. 更新用户头像URL
            String newAvatarUrl = "/user/uploads/avatar/" + fileName;
            user.setAvatar(newAvatarUrl);
            userMapper.updateById(user);
            
            return ResponseResult.success(newAvatarUrl);
        } catch (Exception e) {
            log.error("上传头像失败", e);
            throw new BusinessException("上传头像失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> updatePhone(Long userId, String phone) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 验证手机号格式
        if (!phone.matches("^1[3-9]\\d{9}$")) {
            throw new BusinessException("手机号格式不正确");
        }
        
        user.setPhone(phone);
        userMapper.updateById(user);
        return ResponseResult.success();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> updateEmail(Long userId, String email) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 验证邮箱格式
        if (!email.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$")) {
            throw new BusinessException("邮箱格式不正确");
        }
        
        user.setEmail(email);
        userMapper.updateById(user);
        return ResponseResult.success();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> updateNickname(Long userId, String nickname) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        if (nickname == null || nickname.trim().isEmpty()) {
            throw new BusinessException("昵称不能为空");
        }
        
        user.setNickname(nickname);
        userMapper.updateById(user);
        return ResponseResult.success();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> updateStatus(Long userId, Integer status) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 验证状态值是否合法（假设 1-正常，0-禁用）
        if (status != 0 && status != 1) {
            throw new BusinessException("状态值不合法");
        }
        
        user.setStatus(status);
        userMapper.updateById(user);
        return ResponseResult.success();
    }

    @Override
    public ResponseResult<PageResult<UserInfoResponse>> searchUsers(UserSearchRequest request) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (StringUtils.hasText(request.getUsername())) {
            wrapper.like(User::getUsername, request.getUsername());
        }
        if (StringUtils.hasText(request.getNickname())) {
            wrapper.like(User::getNickname, request.getNickname());
        }
        if (StringUtils.hasText(request.getPhone())) {
            wrapper.like(User::getPhone, request.getPhone());
        }
        if (StringUtils.hasText(request.getEmail())) {
            wrapper.like(User::getEmail, request.getEmail());
        }
        if (request.getStatus() != null) {
            wrapper.eq(User::getStatus, request.getStatus());
        }

        // 分页查询
        Page<User> page = new Page<>(request.getCurrent(), request.getSize());
        Page<User> userPage = userMapper.selectPage(page, wrapper);

        // 转换结果
        List<UserInfoResponse> records = userPage.getRecords().stream()
                .map(user -> {
                    UserInfoResponse response = new UserInfoResponse();
                    BeanUtils.copyProperties(user, response);
                    return response;
                })
                .collect(Collectors.toList());

        // 封装分页结果
        PageResult<UserInfoResponse> pageResult = new PageResult<>();
        pageResult.setRecords(records);
        pageResult.setTotal(userPage.getTotal());
        pageResult.setSize(userPage.getSize());
        pageResult.setCurrent(userPage.getCurrent());

        return ResponseResult.success(pageResult);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> updatePassword(Long userId, UpdatePasswordRequest request) {
        log.info("开始修改密码: userId={}", userId);
        
        // 验证用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            log.error("用户不存在: userId={}", userId);
            throw new BusinessException("用户不存在");
        }

        // 验证原密码是否正确
        if (!passwordEncoder.matches(request.getOldPassword(), user.getPassword())) {
            log.warn("原密码不正确: userId={}", userId);
            throw new BusinessException("原密码不正确");
        }

        // 验证新密码与确认密码是否一致
        if (!request.getNewPassword().equals(request.getConfirmPassword())) {
            log.warn("两次输入的密码不一致: userId={}", userId);
            throw new BusinessException("两次输入的密码不一致");
        }

        // 更新密码
        user.setPassword(passwordEncoder.encode(request.getNewPassword()));
        int rows = userMapper.updateById(user);
        log.info("密码修改完成: userId={}, 影响行数={}", userId, rows);

        return ResponseResult.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> deleteUser(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 逻辑删除用户（将状态设置为禁用）
        user.setStatus(0);
        userMapper.updateById(user);

        return ResponseResult.success();
    }

    @Override
    public ResponseResult<UserInfoResponse> getCurrentUserInfo(String token) {
        // 从token中获取用户ID
        Long userId = jwtUtils.getUserIdFromToken(token);
        return getUserInfo(userId);
    }

    @Override
    public boolean validatePermission(String token, Long userId) {
        log.info("开始验证权限: token={}, userId={}", token, userId);
        try {
            // 如果token以"Bearer "开头，需要去掉这个前缀
            if (token.startsWith("Bearer ")) {
                token = token.substring(7);
                log.info("去掉Bearer前缀后的token: {}", token);
            }
            Long currentUserId = jwtUtils.getUserIdFromToken(token);
            log.info("从token中解析出的用户ID: {}", currentUserId);
            boolean hasPermission = currentUserId.equals(userId);
            log.info("权限验证结果: {}", hasPermission);
            return hasPermission;
        } catch (Exception e) {
            log.error("验证权限时发生异常: ", e);
            return false;
        }
    }

    @Override
    public boolean checkAdminRole(Long userId) {
        log.info("检查用户管理员权限: userId={}", userId);
        
        UserRole userRole = userRoleMapper.selectOne(
            new LambdaQueryWrapper<UserRole>()
                .eq(UserRole::getUserId, userId)
        );
        
        log.info("查询到的用户角色信息: userRole={}", userRole);
        boolean isAdmin = userRole != null && userRole.getRoleId().equals(2L);
        log.info("用户是否具有管理员权限: userId={}, isAdmin={}", userId, isAdmin);
        
        return isAdmin;
    }

    @Override
    public boolean checkSuperAdminRole(Long userId) {
        UserRole userRole = userRoleMapper.selectOne(
            new LambdaQueryWrapper<UserRole>()
                .eq(UserRole::getUserId, userId)
                .eq(UserRole::getRoleId, 1L)  // 1L 是超级管理员角色ID
        );
        return userRole != null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> assignRole(Long userId, Long roleId) {
        // 先检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 删除用户现有角色
        QueryWrapper<UserRole> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.eq("user_id", userId);
        userRoleMapper.delete(deleteWrapper);
        
        // 分配新角色
        UserRole userRole = new UserRole();
        userRole.setUserId(userId);
        userRole.setRoleId(roleId);
        userRoleMapper.insert(userRole);
        
        return ResponseResult.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> updateUserRole(Long userId, Long roleId) {
        // 1. 不允许设置为超级管理员
        if (roleId.equals(1L)) {
            throw new BusinessException("不允许设置为超级管理员");
        }

        // 2. 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 3. 获取角色名称
        String roleName;
        switch (roleId.intValue()) {
            case 2:
                roleName = "管理员";
                break;
            case 4:
                roleName = "商家";
                break;
            default:
                roleName = "普通用户";
                roleId = 3L;
        }

        // 4. 更新用户角色关联
        userRoleMapper.delete(new LambdaQueryWrapper<UserRole>()
            .eq(UserRole::getUserId, userId));
        
        UserRole userRole = new UserRole();
        userRole.setUserId(userId);
        userRole.setRoleId(roleId);
        userRoleMapper.insert(userRole);

        // 5. 更新用户昵称
        user.setNickname(roleName);
        userMapper.updateById(user);

        return ResponseResult.success();
    }

    @Override
    public ResponseResult<List<UserInfoResponse>> getAllUsers() {
        List<User> users = userMapper.selectList(null);
        List<UserInfoResponse> responses = users.stream()
            .map(user -> {
                UserInfoResponse response = new UserInfoResponse();
                BeanUtils.copyProperties(user, response);
                response.setStatus(user.getStatus());
                return response;
            })
            .collect(Collectors.toList());
        return ResponseResult.success(responses);
    }
} 